#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <iostream>

#include <QCamera>
#include <QCameraImageCapture>
#include <QCameraInfo>
#include <QCameraViewfinderSettings>
#include <QList>
#include <QDebug>
#include <QTextStream>
#include <QFile>

#include <QFileDialog>
#include <QVideoWidget>
#include <QMessageBox>
#include <QPixmap>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),

    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    initWindow(); //  初始化界面
    //    setCamera(QCameraInfo::defaultCamera());
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::initWindow() {
    QList<QCameraInfo> camerainfos = QCameraInfo::availableCameras();

    //    caminfo = new QCameraInfo();
    foreach(const QCameraInfo& cameraInfo, camerainfos) {
        QString str = cameraInfo.description();
        QString ss = cameraInfo.deviceName();

        ui->comboBoxSelectCam->addItem(cameraInfo.description());

        cameraList.append(new QCamera(cameraInfo)); // 显示设备名称
    }

    qDebug() << cameraList << endl;
    connect(ui->pushButtonCaptureImage, SIGNAL(clicked()), this,
            SLOT(captureImage()));
    connect(ui->pushButtonSaveImage, SIGNAL(clicked()), this,
            SLOT(saveImage()));

    connect(ui->pushButtonBeginRecord, SIGNAL(clicked()), this,
            SLOT(startRecord()));
    connect(ui->pushButtonEndRecord, SIGNAL(clicked()), this,
            SLOT(stopRecord()));
    connect(ui->pushButtonQuit,      SIGNAL(clicked()), this, SLOT(quitApp()));
    connect(ui->pushButtonSaveVideo, SIGNAL(clicked()), this, SLOT(saveVideo()));
    showVideo();
}

/**
 * @details 显示摄像头在下拉框中,给按钮绑定事件
 * @brief cameras
 */
void MainWindow::setCamera(const QCameraInfo& cameraInfo) {
    //    camera.reset(new QCamera(cameraInfo));
    //    connect(camera.data(), &QCamera::stateChanged, this,
    // &MainWindow::updateCameraState);
    //    connect(camera.data(), QOverload<QCamera::Error>::of(&QCamera::error),
    // this, &MainWindow::displayCameraError);

    //    m_mediaRecorder.reset(new QMediaRecorder(camera.data()));
    //    connect(m_mediaRecorder.data(), &QMediaRecorder::stateChanged, this,
    // &MainWindow::updateRecorderState);

    //    m_imageCapture.reset(new QCameraImageCapture(camera.data()));

    //    connect(m_mediaRecorder.data(), &QMediaRecorder::durationChanged,
    // this, &Camera::updateRecordTime);
    //    connect(m_mediaRecorder.data(),
    // QOverload<QMediaRecorder::Error>::of(&QMediaRecorder::error),
    //            this, &Camera::displayRecorderError);

    //    m_mediaRecorder->setMetaData(QMediaMetaData::Title,
    // QVariant(QLatin1String("Test Title")));

    //    connect(ui->exposureCompensation, &QAbstractSlider::valueChanged,
    // this, &Camera::setExposureCompensation);

    //    camera->setViewfinder(ui->viewfinder);

    //    updateCameraState(camera->state());
    //    updateLockStatus(camera->lockStatus(), QCamera::UserRequest);
    //    updateRecorderState(m_mediaRecorder->state());

    //    connect(m_imageCapture.data(),
    // &QCameraImageCapture::readyForCaptureChanged, this,
    // &Camera::readyForCapture);
    //    connect(m_imageCapture.data(), &QCameraImageCapture::imageCaptured,
    // this, &Camera::processCapturedImage);
    //    connect(m_imageCapture.data(), &QCameraImageCapture::imageSaved, this,
    // &Camera::imageSaved);
    //    connect(m_imageCapture.data(), QOverload<int,
    // QCameraImageCapture::Error, const QString
    // &>::of(&QCameraImageCapture::error),
    //            this, &Camera::displayCaptureError);

    //    connect(camera.data(), QOverload<QCamera::LockStatus,
    // QCamera::LockChangeReason>::of(&QCamera::lockStatusChanged),
    //            this, &Camera::updateLockStatus);

    //    ui->captureWidget->setTabEnabled(0,
    // (camera->isCaptureModeSupported(QCamera::CaptureStillImage)));
    //    ui->captureWidget->setTabEnabled(1,
    // (camera->isCaptureModeSupported(QCamera::CaptureVideo)));

    //    updateCaptureMode();
    //    camera->start();
    QList<QCameraInfo> cameras = QCameraInfo::availableCameras();

    foreach(const QCameraInfo& cameraInfo, cameras) {
        ui->comboBoxSelectCam->addItem(cameraInfo.description());
    } // 读取所有的摄像头填入下拉框中
    connect(ui->pushButtonCaptureImage, SIGNAL(clicked()), this,
            SLOT(captureImage()));// 给按钮添加槽事件
    connect(ui->pushButtonSaveImage, SIGNAL(clicked()), this,
            SLOT(saveImage()));

    connect(ui->pushButtonBeginRecord, SIGNAL(clicked()), this,
            SLOT(beginRecord()));
    connect(ui->pushButtonEndRecord, SIGNAL(clicked()), this,
            SLOT(endRecord()));
    connect(ui->pushButtonSaveVideo, SIGNAL(clicked()), this, SLOT(saveVideo()));
    showVideo();
}

void MainWindow::on_pushButtonOpenCam_clicked()
{
    ui->comboBoxSelectCam->currentText();
    m_camera->start();


    //    showVideo();
    ui->statusBar->showMessage(tr("open cam sucess"), 5000);
}

void MainWindow::showVideo() {
    //    m_camera = new QCamera(cameraList.at(1));
    m_camera = new QCamera();
    viewfinder = new QCameraViewfinder();
    imageCapture = new QCameraImageCapture(m_camera);

    ui->horizontalLayout_View->addWidget(viewfinder);
    ui->label_Display->setScaledContents(true);
    viewfinder->show();                  // 显示获取的摄像头图像
    m_camera->setViewfinder(viewfinder); // 设置输出的位置

    imageCapture = new QCameraImageCapture(m_camera);

    imageCapture->setCaptureDestination(QCameraImageCapture::CaptureToFile);
    m_camera->setCaptureMode(QCamera::CaptureMode::CaptureVideo);

    //    //设置采集模式
    //    camera->setCaptureMode(QCamera::CaptureStillImage);              //
    // 将其采集为图片
    m_camera->setCaptureMode(QCamera::CaptureMode::CaptureViewfinder); // 将其采集到取景器中
    bindRecoder(m_camera);

    // 开启摄像头
    connect(imageCapture, SIGNAL(imageCaptured(int,QImage)), this,
            SLOT(displayImage(int,QImage)));
}

/**
 * @details 播放按钮点击事件
 * @brief MainWindow::on_pushButtonPlay_clicked
 */
void MainWindow::on_pushButtonPlay_clicked()
{
    QList<QCameraInfo> cameras = QCameraInfo::availableCameras();

    foreach(const QCameraInfo& cameraInfo, cameras) {
        if (cameraInfo.deviceName() ==
            "mycamera") qDebug() << "hello " << cameraInfo.deviceName() << "!" <<
                endl;
    }
}

void MainWindow::captureImage() {
    ui->statusBar->showMessage(tr("正在捕获图片"), 1000);
    imageCapture->capture();
}

/**
 * @details 保存图片
 * @brief MainWindow::saveImage
 */
void MainWindow::saveImage()
{
    //    QMessageBox message(QMessageBox::NoIcon, "Title", "Content with
    // icon.");
    //    //    message.setIconPixmap(QPixmap("icon.png"));

    //    QString fileName=QFileDialog::getSaveFileName(this, tr("save file"),
    // QDir::homePath(), tr("jpeg(*.jpg)"));
    //    if(fileName.isEmpty()) {
    //        ui->statusBar->showMessage(tr("save cancel"), 5000);
    //        return;
    //    }
    //    const QPixmap* pixmap=ui->label_Display->pixmap();
    //    if(pixmap) {
    //        //        captureImage();
    //        pixmap->save(fileName);
    //        ui->statusBar->showMessage(tr("save OK"), 5000);

    //        message.setText("保存成功!");
    //        message.exec();

    //    }else {
    //        message.setText("保存失败");
    //        message.exec();
    //    }
}

void MainWindow::quitApp() {
    qApp->exit(0);
}

/**
 * @brief MainWindow::displayImage
 * @param image
 */
void MainWindow::displayImage(int, QImage image) {
    ui->label_Display->setPixmap(QPixmap::fromImage(image));
    ui->statusBar->showMessage(tr("捕获成功"), 5000);
}

/**
 * @details 显示所有的摄像头,并选择,
 * @brief MainWindow::getDeviceNamge
 * @param index
 * @return
 */
QString MainWindow::getDeviceNamge(int index) {
    if (((index < 0) || (index >= 5))) {
        return QString();
    }
    return QCameraInfo::availableCameras().at(index).description();
}

/*
   @brief          设置录制格式
   @param  camera  摄像头对象
   @return
   windows 下测试无效，其他解决方案 用QtMEL 详情 http://kibsoft.ru/
 */
void MainWindow::bindRecoder(QCamera *camera)
{
    m_mediaRecorder = new QMediaRecorder(camera, this);
    connect(m_mediaRecorder,
            static_cast<void (QMediaRecorder::*)(QMediaRecorder::Error)>(&
                                                                         QMediaRecorder
                                                                         ::
                                                                         error),
            [ = ](QMediaRecorder::Error error) {
        qDebug() << error;
    });
    connect(m_mediaRecorder, &QMediaRecorder::statusChanged,
            [ = ](QMediaRecorder::Status status) {
        qDebug() << status;
    });
}

void MainWindow::saveVideo() {}

void MainWindow::startRecord() {
    if (!m_camera) return;

    m_camera->focus();

    //    // 设置音频编码格式
    //    QAudioEncoderSettings audioSettings;
    //    audioSettings.setCodec("audio/amr");
    //    audioSettings.setQuality(QMultimedia::HighQuality);

    // mMediaRecorder->setAudioSettings(audioSettings);

    QVideoEncoderSettings videosettings = m_mediaRecorder->videoSettings();

    videosettings.setResolution(640, 480);
    videosettings.setQuality(QMultimedia::VeryHighQuality);
    videosettings.setFrameRate(30.0);
    videosettings.setCodec("video/mp4");

    m_mediaRecorder->setVideoSettings(videosettings);
    bool ret =
        m_mediaRecorder->setOutputLocation(QUrl::fromLocalFile("testvideo.mp4"));

    qDebug() << "ret: " << ret;
    m_mediaRecorder->record();

    updateRecordTime();
}

void MainWindow::updateRecordTime()
{
    QString str = QString("Recorded %1 sec").arg(
        m_mediaRecorder->duration() / 1000);

    ui->statusBar->showMessage(str);
}

void MainWindow::pauseRecord()
{
    m_mediaRecorder->pause();
}

void MainWindow::stopRecord()
{
    m_mediaRecorder->stop();
}

void MainWindow::on_pushButtonCaptureImage_clicked()
{}

void MainWindow::on_pushButtonSaveImage_clicked()
{}

void MainWindow::on_pushButtonBeginRecord_clicked()
{
    startRecord();
}

void MainWindow::on_pushButtonEndRecord_clicked()
{
    stopRecord();
}

void MainWindow::on_pushButtonSaveVideo_clicked()
{}


void MainWindow::on_pushButtonOpenFFmpeg_clicked()
{
    ffmpegWindow.show();

    //    qDebug() << m_camera->state() << endl;
    //    qDebug() << typeid(m_camera->state()).name() << endl;

    //    qDebug() << camera->state() == "ActiveState";

    if (m_camera->state() == QCamera::ActiveState) {
        m_camera->stop();
    }
}

void MainWindow::on_pushButtonCloseCam_clicked()
{
    m_camera->stop();
}

void MainWindow::on_pushButtonDetect_clicked()
{
    QString recordability = "if camara capture" +
                            QString::number(m_camera->isCaptureModeSupported(
                                                QCamera::CaptureVideo));
    QMessageBox message(QMessageBox::NoIcon,
                        "cam to record",
                        recordability);

    message.exec();
}

void MainWindow::on_comboBoxSelectCam_currentIndexChanged(const QString& arg1)
{}
